/**
 * ===========================================================================
 * File:   msg.c
 * Author: gustavo
 *
 * Created on October 25, 2010, 3:22 PM
 * ---------------------------------------------------------------------------
 *
 *  Copyright (C) 2010  Gustavo Teodoro Laureano - <gustavoengdm@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * ===========================================================================
 **/

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include <errno.h>

#include "msg.h"

#define MSG_MAX_LENGTH		512

static char _msg_[MSG_MAX_LENGTH + 10];
static int _type_ = MSG_NOTICE;
static int _msg_flag_ = 0;

/**
 * =============================================================================
 * =                               Defines                                     =
 * =============================================================================
 **/
#define NOTICE_COLOR    MSG_COLOR_GREEN
#define WARNING_COLOR   MSG_COLOR_YELLOW
#define ERROR_COLOR     MSG_COLOR_RED

/**
 * =============================================================================
 * =                      _msg functions implementation                        =
 * =============================================================================
 **/
void msg_set_message(int type, char * template, ...) {
	va_list ap;

	_type_ = type;

	va_start(ap, template);
	vsprintf(_msg_, template, ap);
	va_end(ap);
	_msg_flag_ = 1;
}

void msg_print_message(void) {

	if (_msg_flag_ == 0) {
		msg_notice("There is no message!\n");
		return;
	}

	msg_set_attributes(MSG_ATTR_RESET, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
	switch (_type_) {
		case MSG_ERROR:
			msg_set_attributes(MSG_ATTR_BRIGHT, ERROR_COLOR, MSG_COLOR_BLACK);
			fprintf(stderr, MSG_ERROR_MESSAGE);
			break;
		case MSG_WARNING:
			msg_set_attributes(MSG_ATTR_BRIGHT, WARNING_COLOR, MSG_COLOR_BLACK);
			fprintf(stderr, MSG_WARNING_MESSAGE);
			break;
		case MSG_NOTICE:
			msg_set_attributes(MSG_ATTR_BRIGHT, NOTICE_COLOR, MSG_COLOR_BLACK);
			fprintf(stderr, MSG_NOTICE_MESSAGE);
			break;
	}
	msg_set_attributes(MSG_ATTR_RESET, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
	fprintf(stderr, "%s", _msg_);
	_msg_flag_ = 0;
}

void msg_set_attributes(int attr, int fg, int bg) {
	char command[13];
	/* Command is the control command to the terminal */
	sprintf(command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40);
	fprintf(stderr, "%s", command);
}

void msg_reset_attributes(void) {
	msg_set_attributes(MSG_ATTR_RESET, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
}

void msg_print(int type, char *template, ...) {
	va_list ap;

	msg_set_attributes(MSG_ATTR_RESET, DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
	switch (type) {
		case MSG_ERROR:
			//msg_set_attributes(MSG_ATTR_BRIGHT, ERROR_COLOR, MSG_COLOR_BLACK);
			msg_set_attributes(MSG_ATTR_BRIGHT, ERROR_COLOR, DEFAULT_BACKGROUND);
			fprintf(stderr, MSG_ERROR_MESSAGE);
			break;
		case MSG_WARNING:
			//msg_set_attributes(MSG_ATTR_BRIGHT, WARNING_COLOR, MSG_COLOR_BLACK);
			msg_set_attributes(MSG_ATTR_BRIGHT, WARNING_COLOR, DEFAULT_BACKGROUND);
			fprintf(stderr, MSG_WARNING_MESSAGE);
			break;
		case MSG_NOTICE:
			//msg_set_attributes(MSG_ATTR_BRIGHT, NOTICE_COLOR, MSG_COLOR_BLACK);
			msg_set_attributes(MSG_ATTR_BRIGHT, NOTICE_COLOR, DEFAULT_BACKGROUND);
			fprintf(stderr, MSG_NOTICE_MESSAGE);
			break;
	}
	msg_reset_attributes();
			
	va_start(ap, template);
	vfprintf(stderr, template, ap);
	va_end(ap);

	if (type == MSG_ERROR) {
		exit(EXIT_FAILURE);
	}
	
}

void msg_print_text(char *template, ...) {
	va_list ap;
	va_start(ap, template);
	vfprintf(stderr, template, ap);
	va_end(ap);
}

/**
 * =============================================================================
 * =                  Auxiliary functions implementation                       =
 * =============================================================================
 **/
void errno_print(char * s) {
	msg_print(MSG_ERROR, "%s error %d, %s\n", s, errno, strerror(errno));
}

void errno_exit(char * s) {
	msg_print(MSG_ERROR, "%s error %d, %s\n", s, errno, strerror(errno));
	exit(EXIT_FAILURE);
}
